package com.taomus.mytools.helper.web;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.oro.text.perl.Perl5Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.taomus.mytools.helper.ObjectHelper;
import com.taomus.mytools.helper.StringHelper;
import com.taomus.mytools.helper.web.annotations.Length;
import com.taomus.mytools.helper.web.annotations.NotEmpty;
import com.taomus.mytools.helper.web.annotations.NotNull;
import com.taomus.mytools.helper.web.annotations.RegExp;

public class VerifyHelper {
	private static Logger LOGGER = LoggerFactory.getLogger(VerifyHelper.class);
	private Object src = null;
	List<VerifyResult> verifyResults = new ArrayList<>();
	
	public VerifyHelper(Object inSrc){
		this.src = inSrc;
	}
	
	public boolean verify(HttpServletRequest request) throws IllegalArgumentException, IllegalAccessException{
		Field[] fields = src.getClass().getDeclaredFields();
		boolean ifVerify = true;
		for(Field field:fields){
			field.setAccessible(true);
			if(!verifyField(field,src)){
				if(ObjectHelper.isNotNull(request)){
					request.setAttribute("VerifyResults", this.verifyResults);
				}
				ifVerify = false;
			}
		}
		return ifVerify;
	}
	private void LOG(String log){
		LOGGER.info(log);
	}
	private boolean isNotNull(Object src,String name,String message){
		if(ObjectHelper.isNotNull(src)){
			return true;
		}
		LOG(name+":"+message);
		this.verifyResults.add(new VerifyResult(name, message));
		return false;
	}
	private boolean isNotEmpty(Object src,String name,String message){
		if(src instanceof String){
			if(StringHelper.isNotEmpty((String) src)){
				return true;
			}
		}
		LOG(name+":"+message);
		this.verifyResults.add(new VerifyResult(name, message));
		return false;
	}
	
	private boolean regExp(String pattern,Object src,String name,String message){
		String input = String.valueOf(src);
		Perl5Util perl5 = new Perl5Util();
		if(perl5.match(pattern, input)){
			return true;
		}
		LOG(name+":"+message);
		this.verifyResults.add(new VerifyResult(name, message));
		return false;
	}
	private boolean length(Object src,Length len,String name){
		String input = String.valueOf(src);
		int length = input.length();
		boolean is = true;
		switch(len.method()){
		case LE:
			is = length <= len.value() ? true:false;
			break;
		case LT:
			is =  length < len.value() ? true:false;
			break;
		case GE:
			is =  length >= len.value() ? true:false;
			break;
		case GT:
			is =  length > len.value() ? true:false;
			break;
		case NE:
			is =  length != len.value() ? true:false;
			break;
		case EQ:
			is =  length == len.value() ? true:false;
			break;
		}
		if(is){
			return true;
		}
		LOG(name+":"+len.message());
		this.verifyResults.add(new VerifyResult(name, len.message()));
		return false;
	}
	private boolean verifyField(Field field,Object src) throws IllegalArgumentException, IllegalAccessException {
		NotNull notNull = field.getAnnotation(NotNull.class);
		NotEmpty notEmpty = field.getAnnotation(NotEmpty.class);
		RegExp regExp = field.getAnnotation(RegExp.class);
		Length length = field.getAnnotation(Length.class);
		Object dest = field.get(src);
		boolean isNotNull = true;
		boolean isNotEmpty = true;
		boolean isRegExp = true;
		boolean isLength = true;
		if(null != notNull){
			isNotNull = this.isNotNull(dest,field.getName(),notNull.message());
		}
		if(null != notEmpty){
			isNotEmpty = this.isNotEmpty(dest,field.getName(),notEmpty.message());
		}
		if(null != length){
			isLength = this.length(dest,length,field.getName());
		}
		if(null != regExp){
			isRegExp = this.regExp(regExp.value(),dest,field.getName(),regExp.message());
		}
		if(isNotNull&&isNotEmpty&&isRegExp&&isLength){
			return true;
		}
		return false;
	}
}
